package client;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;


import pojo.ChessOnlineRoom;
import pojo.League;
import pojo.UserAccount;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import chessman.Chessman;
import util.Utils;
import view.ChessOnlineView;

import view.ConnectView;

import view.CreateLeagueRoomForm;

import view.CreateRoomForm;
import view.HomePageView;
import view.JoinLeagueForm;
import view.LobbyView;
import view.PlayGameView;
import view.RoomView;
import transfer.StringData;


public class Client implements  Runnable {
	private static final String CONNECT_VIEW_ID = "connect-view";
	private static final String PLAY_GAME_VIEW_ID = "play-game-view";
	private static final String CREATE_ROOM_VIEW_ID = "create-room-view";
	private static final String CREATE_LEAGUE_ROOM_VIEW_ID = "create-league-room-view";
	private static final String JOIN_LEAGUE_VIEW_ID = "join-league-view";
	public static final String HOME_PAGE_VIEW_ID = "home-page-view";
	public static final String LOBBY_VIEW_ID = "lobby-view";
	public static final String ROOM_VIEW_ID = "room-view";
	
	private JFrame frame;
	private UserAccount acc = null;

	private String ipServer = "localhost";
	private int port = 3579;

	private ClientWorker cw = null;
	private Socket client;
	//int id = -1;

	

	// View management
	private Map<String, ChessOnlineView> mViews = new HashMap<>();
	// User management
	private PlayGameView mPlayGameView;
	

	private ConnectView mConnectView;
	private HomePageView mHomePageView;
	private LobbyView mLobbyView;
	private RoomView mRoomView;
	private CreateRoomForm mCreateRoomView;
	private CreateLeagueRoomForm mCreateLeagueRoomView;
	private JoinLeagueForm mJoinLeagueView;

	public LobbyView getmLobbyView() {
		return mLobbyView;
	}

	public void setmLobbyView(LobbyView mLobbyView) {
		this.mLobbyView = mLobbyView;
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Client window = new Client();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 * 
	 * @throws IOException
	 */
	public Client() throws IOException {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 * 
	 * @throws IOException
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("Client");
		frame.setBounds(0, 50, 800, 600);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout());
		//new Thread(this).start();
		

		frame.addWindowListener(new WindowAdapter() {
	        public void windowClosing(WindowEvent winEvt) {
	        	if(cw != null){
	        		cw.sendObject(new StringData("Disconnect",null));
		            System.exit(0);
	        	}
	        	
	        }
	    });
		showConnectView();
	}


	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			client = new Socket(ipServer, port);
			if (client.isConnected()){
				cw = new ClientWorker(client, this);
				new Thread(cw).start();
				showHomePageView();
			
				
			}

		}catch  (ConnectException ce){
			JOptionPane.showMessageDialog(frame, "Không tìm thấy server!!!!");
		}
		catch (UnknownHostException uv) {
			uv.printStackTrace();	
		} catch (IOException ev) {	
			ev.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void loadTeamA(Client client) {
		showPlayGameView(0);
	}

	public void loadTeamB(Client client) {
		showPlayGameView(1);
	}

	public ClientWorker getCw() {
		return cw;
	}

	public void setCw(ClientWorker cw) {
		this.cw = cw;
	}
	public UserAccount getAcc() {
		return acc;
	}

	public void setAcc(UserAccount acc) {
		this.acc = acc;
	}
	
public String getIpServer() {
		return ipServer;
	}

	public void setIpServer(String ipServer) {
		this.ipServer = ipServer;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	/*	private void addViewComponent(String id, ChessOnlineView component, LayoutManager layout) {
		this.frame.getContentPane().setLayout(layout);
		this.frame.getContentPane().add(component);
		this.addView(id, component);
	}*/
	private void addViewComponent(String id, ChessOnlineView component, String layout) {
		this.frame.getContentPane().add(component, layout);
		this.addView(id, component);
	}
	private void addView(String id, ChessOnlineView view) {
		if(!this.mViews.containsKey(id)) {
			this.mViews.put(id, view);
		}
	}
	
	private void removeView(String id, ChessOnlineView view) {
		this.mViews.remove(id);
		this.frame.remove(view);
		view = null;
	}
	
	public void showView(String id) {
		for(ChessOnlineView view : this.mViews.values()) {
			view.setVisible(false);
			view.onHide();
		}
		
		this.mViews.get(id).onShow();
		this.mViews.get(id).setVisible(true);
		this.frame.invalidate();
	}
	public void showPlayGameView(int teamID) {
		if(mPlayGameView != null) {
			removeView(PLAY_GAME_VIEW_ID, mPlayGameView);
		}
		mPlayGameView = new PlayGameView(this, teamID);
		this.addViewComponent(PLAY_GAME_VIEW_ID, mPlayGameView, BorderLayout.CENTER);
		
		this.showView(PLAY_GAME_VIEW_ID);
	}


	public void setCurrentTurn(int currentTurn) {
		mPlayGameView.setCurrentTurn(currentTurn);
	}

	public void refreshBoard(Chessman[] chess) {	
		mPlayGameView.refreshBoard(chess);
		
	}

	public void refreshLabelTurn (int turn){
		mPlayGameView.refreshLabelTurn(turn);
	}
	
	public HomePageView getmHomePageView() {
		return mHomePageView;
	}

	public void setmHomePageView(HomePageView mHomePageView) {
		this.mHomePageView = mHomePageView;
	}

	public void appenChatString(String content) {
		mPlayGameView.appendChatString(content);
		
	}
	public PlayGameView getmPlayGameView() {
		return mPlayGameView;
	}

	public void setmPlayGameView(PlayGameView mPlayGameView) {
		this.mPlayGameView = mPlayGameView;
	}

	public void showConnectView() {
		
		
		if(mConnectView != null) {
			removeView(Client.CONNECT_VIEW_ID, mConnectView);
		}
		
		mConnectView = new ConnectView(this);
		this.addViewComponent(Client.CONNECT_VIEW_ID, mConnectView, BorderLayout.CENTER);
		this.showView(Client.CONNECT_VIEW_ID);
		
	}
	public void showHomePageView() {
		// Clear the SESSION
			Utils.removeUserSession();
		
		if(mHomePageView != null) {
			removeView(Client.HOME_PAGE_VIEW_ID, mHomePageView);
		}
		
		mHomePageView = new HomePageView(this);
		this.addViewComponent(Client.HOME_PAGE_VIEW_ID, mHomePageView, BorderLayout.CENTER);
		this.showView(Client.HOME_PAGE_VIEW_ID);
		
	}
	public void showLobbyView(boolean isLeague) {
		if(mLobbyView != null) {
			removeView(Client.LOBBY_VIEW_ID, mLobbyView);
		}
		
		mLobbyView = new LobbyView(this, isLeague);
		this.addViewComponent(Client.LOBBY_VIEW_ID, mLobbyView, BorderLayout.CENTER);
		
		mLobbyView.showRoom();
		
		this.showView(LOBBY_VIEW_ID);
	}

	public void showRoomView(ChessOnlineRoom room) {
		if(mRoomView != null) {
			removeView(Client.ROOM_VIEW_ID, mRoomView);
		}
		mRoomView = new RoomView(this, room);
		this.addViewComponent(Client.ROOM_VIEW_ID, mRoomView, BorderLayout.CENTER);
		
		this.showView(ROOM_VIEW_ID);
	}


	
	


	public void showCreateRoomView() {
		if(this.mCreateRoomView != null) {
			this.removeView(CREATE_ROOM_VIEW_ID, mCreateRoomView);
		}
		
		this.mCreateRoomView = new CreateRoomForm(this);
		
		this.addViewComponent(CREATE_ROOM_VIEW_ID, this.mCreateRoomView, BorderLayout.CENTER);
		this.showView(CREATE_ROOM_VIEW_ID);
	}
	
	public void showCreateLeagueRoomView() {
		if(this.mCreateLeagueRoomView != null) {
			this.removeView(CREATE_LEAGUE_ROOM_VIEW_ID, mCreateLeagueRoomView);
		}
		
		this.mCreateLeagueRoomView = new CreateLeagueRoomForm(this);
		
		this.addViewComponent(CREATE_LEAGUE_ROOM_VIEW_ID, this.mCreateLeagueRoomView, BorderLayout.CENTER);
		this.showView(CREATE_LEAGUE_ROOM_VIEW_ID);
	}
	
	public void showJoinLeagueView(League league) {
		if(this.mJoinLeagueView != null) {
			this.removeView(JOIN_LEAGUE_VIEW_ID, mJoinLeagueView);
		}
		
		this.mJoinLeagueView = new JoinLeagueForm(this, league);
		
		this.addViewComponent(JOIN_LEAGUE_VIEW_ID, this.mJoinLeagueView, BorderLayout.CENTER);
		this.showView(JOIN_LEAGUE_VIEW_ID);
	}


}
